# -*- coding: UTF-8 -*- #
"""
-------真正的勇士， 敢于直面惨淡的Warning、 敢于正视淋漓的Error-----
@author : 贾鹏博
@file : base_api.py
@time : 2022/6/29 21:20
"""
import json
import requests
from apitest.电子商城接口框架.utils.Logger import logger

"""
问题1： 接口里面直接使用了requests。
    解决方案：在 base_api 中添加 send 公共方法，并加上日志
问题2： 大量重复的 base_url。 
    解决方案：在构造函数，实例化 base_url 。并在 send 方法中，直接拼接。这样在子类的方法就无需重复编写 self.base_url
优化3： token获取也放在基类的构造函数里
"""


class BaseApi:

    def __init__(self, base_url, role=None):
        # 初始化 基地址，后面直接拼接
        self.base_url = base_url
        # 获取对应的角色信息
        if role:
            self.role = role

    def __set_token(self, request_infos: dict):
        """
        除登录接口之外，基本所有接口都需要设置 token。
        解决方案：
            1、在 发起接口请求之前，就获取 token 信息
            2、获取 token 信息之后，塞入到请求信息之中
                1、除了 method 和 url 之外，所有的其他信息（包括 header，params，json，data 等其他参数，都会塞入至 kwargs 不定长参数中）
                2、cart_api -> send -> 获取 kwargs -> 在 kwargs 中塞入 header(鉴权)信息
            问题二： 如果有 2个 token 存在，怎么处理？
                1、不同角色有不同的 token 信息
        :return:
        """
        # 服务端获取 token
        admin_url = "admin/auth/login"
        admin_data = {"username": "admin123", "password": "admin123", "code": ""}
        admin_r = requests.request("post", self.base_url + admin_url, json=admin_data)
        self.token = admin_r.json()["data"]["token"]
        # 客户端获取 token
        client_url = "wx/auth/login"
        client_data = {"username": "user123", "password": "user123"}
        client_r = requests.request("post", self.base_url + client_url, json=client_data)
        self.client_token = client_r.json()["data"]["token"]
        # 如果是 admin，那么就塞入 admin 的 token，并添加头信息
        # 如果是 user ，那么就塞入用户 user 的 token，并添加头信息
        if self.role == "admin":
            self.final_token = {"X-Litemall-Admin-Token": self.token}
        elif self.role == "client":
            self.final_token = {"X-Litemall-Token": self.client_token}

        # 获取 headers ，如果请求本身有头信息，那么就把 token 信息更新进去（不会覆盖原有的 header）
        if request_infos.get("headers"):
            request_infos["headers"].update(self.final_token)
        else:
            request_infos["headers"] = self.final_token
        return request_infos

    def send(self, method, url, **kwargs):
        kwargs = self.__set_token(kwargs)
        # 问题一：接口里直接使用了 requests 库。   解决方案：在 base_api 中添加公共的 send 方法
        # 问题二：大量重复的 base_url。   解决方案： 在构造函数中，实例化base_url,并且在 send 方法中，直接拼接（子类方法无需重复编写self.base_url）
        r = requests.request(method, self.base_url + url, **kwargs)
        logger.debug(f'接口的url是{url},接口的响应值为{json.dumps(r.json(), indent=2, ensure_ascii=False)}')
        return r.json()
